package com.example.wordpress;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import com.facebook.FacebookRequestError;
import com.facebook.HttpMethod;
import com.facebook.Request;
import com.facebook.RequestAsyncTask;
import com.facebook.Response;
import com.facebook.Session;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.Html;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

/**
 * Controlador del activity PostEditor
 * @author Ignacio Javier Kovacs, Armando Ezequiel Puerta
 *
 */

public class EditorCtrl implements OnClickListener {

	public static final int REQUEST_TAKE_PHOTO = 1;
	public static final int REQUEST_FACEBOOK_LOGIN = 2;
	
	private final EditorView postEditorView;
	private final Database database;
	private final Gallery gallery;
	
	private int post_id;
	private Post post;
	private Blog blog;
	
	// PARA FACEBOOK
	private static final List<String> PermisosNecesarios = Arrays.asList("publish_actions");
	// -------------

	public EditorCtrl(EditorView view, Database db, Gallery glry) {
		
		postEditorView = view;
		database = db;
		blog = database.getBlog(getBlogId());
		post_id = getPostId();
		gallery = glry;
		
		if(post_id != MainActivityCtrl.NEW_POST) {
			/* Obtener los datos actualizados del post. */
			AsyncHttpGet client = new AsyncHttpGet(new SyncPostListener());
			client.putHeader("Authorization", "Bearer " + blog.getToken());
			client.putHeader("Content-Type", "application/json; charset=utf-8");
			client.putHeader("context", "edit");
			client.execute(new String[] {Blog.REST_URL + "/sites/" + String.valueOf(blog.getId()) + "/posts/" + String.valueOf(post_id)});
		}
	}
	
	public void onPause() {
		postEditorView.dismissProgressDialog();
	}

	/**
	 * Manejador de evento onClick de la View PostEditor.
	 */
	@Override
	public void onClick(View v) {
		
		switch(v.getId()) {		
		
		case(R.id.button_camera):
			dispatchTakePictureIntent();
			break;
		}
	}
	
	/**
	 * Manejador de eventos del menu de la View PostEditor.
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()) {
			case R.id.menu_send_post:
				sendPost();
				break;
			case R.id.menu_delete_post:
				deletePost();
				break;
		}
		return true;
	}
	
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
//		TODO: Obtener la imagen tomada, guardarla (archivo, variable). Convertirla a jpg.
		if(requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
			gallery.addPhoto((Bitmap) data.getExtras().get("data"));
		}
		
		if(requestCode == REQUEST_FACEBOOK_LOGIN && resultCode == Activity.RESULT_OK) {
			shareOnFacebook(post);
		}
	}

	public void onBackPressed() {
		//TODO: Que no pregunte cuando no hay cambios, agregar opci�n para guardar localmente. 
//		AlertDialog.Builder builder = new AlertDialog.Builder(postEditorView.getActivity());
//
//	    builder.setTitle("WordPress");
//	    builder.setMessage("Discard changes?");
//
//	    builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
//
//	        public void onClick(DialogInterface dialog, int which) {
//	        	postEditorView.getActivity().setResult(Activity.RESULT_OK, null);
//	    		postEditorView.getActivity().finish();
//	            dialog.dismiss();
//	        }
//
//	    });
//
//	    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
//
//	        @Override
//	        public void onClick(DialogInterface dialog, int which) {
//	            dialog.dismiss();
//	        }
//	    });
//
//	    AlertDialog alert = builder.create();
//	    alert.show();
    	postEditorView.getActivity().setResult(Activity.RESULT_OK, null);
		postEditorView.getActivity().finish();
	}
	
	/**
	 * Crea un nuevo post y lo almacena localmente, si es requerido envia un mensaje a Facebook para difundir la nota.
	 */
	private void sendPost() {
		if(post_id != MainActivityCtrl.NEW_POST) {
			AsyncHttpPost client = new AsyncHttpPost(new SendPostListener());
			client.putHeader("Authorization", "Bearer " + blog.getToken());
			client.putHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			client.putValue("title", postEditorView.getPostTitle());
			client.putValue("content", postEditorView.getPostContent());
			client.putValue("excerpt", postEditorView.getPostExcerpt());
			client.putValue("status", postEditorView.getStatus());
			client.putValue("format", "standard");
			client.execute(new String[] {Blog.REST_URL + "/sites/" + String.valueOf(blog.getId()) + "/posts/" + String.valueOf(post_id)});
		}
		else {
			if(gallery.size() != 0) {
				AsyncHttpPostImage client = new AsyncHttpPostImage(new SendPostListener());
				client.putHeader("Authorization", "Bearer " + blog.getToken());
				client.putValue("title", postEditorView.getPostTitle());
				client.putValue("content", postEditorView.getPostContent());
				client.putValue("excerpt", postEditorView.getPostExcerpt());
				client.putValue("status", postEditorView.getStatus());
				client.putImages(gallery.getPhotos());
				client.execute(new String[] {Blog.REST_URL + "/sites/" + String.valueOf(blog.getId()) + "/posts/new"});
			}
			else {
				AsyncHttpPost client = new AsyncHttpPost(new SendPostListener());
				client.putHeader("Authorization", "Bearer " + blog.getToken());
				client.putHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
				client.putValue("title", postEditorView.getPostTitle());
				client.putValue("content", postEditorView.getPostContent());
				client.putValue("excerpt", postEditorView.getPostExcerpt());
				client.putValue("status", postEditorView.getStatus());
				client.putValue("format", "standard");
				client.execute(new String[] {Blog.REST_URL + "/sites/" + String.valueOf(blog.getId()) + "/posts/new"});
			}
		}
		

	}
	
	public void shareOnFacebook(Post postInfo) {
		if(postEditorView.getFacebookCheckBox().isChecked()) {
			String post[] = new String [5];
			post[0] = postInfo.getTitle();
			post[1] = Html.fromHtml(postInfo.getExcerpt()).toString(); //postInfo.getExcerpt();
			post[2] = Html.fromHtml(postInfo.getContent()).toString(); // postInfo.getContent();
			post[3] = postInfo.getUrl();
			post[4] = (postInfo.getImageUrls().size() != 0)? postInfo.getImageUrls().get(0) : "http://rolandocaldas.com/wp-content/uploads/2013/05/wordpress.png";

			Session sesion = Session.getActiveSession();
		    if (sesion != null){  
		        List<String> permisos = sesion.getPermissions();
		        if (!esSubconjunto(PermisosNecesarios, permisos)) {
		            Session.NewPermissionsRequest nuevosPermisosRequeridos = new Session.NewPermissionsRequest(postEditorView.getActivity(), PermisosNecesarios);
		            sesion.requestNewPublishPermissions(nuevosPermisosRequeridos);
		            return;
		        }
		        
		        Bundle postParametros = new Bundle();
		        postParametros.putString("name", post[0]);
		        postParametros.putString("caption", post[1]);
		        postParametros.putString("description", post[2]);
		        postParametros.putString("link", post[3]);
		        postParametros.putString("picture", post[4]);
		        
		        Request.Callback callback= new Request.Callback() {
		            public void onCompleted(Response respuesta) {
		                JSONObject graphResponse = null;
		                String postId = null;
		                try {
		                	graphResponse = respuesta.getGraphObject().getInnerJSONObject();
		                    postId = graphResponse.getString("id");
		                } catch (JSONException e) {
		                    Log.i("[JSONException]", e.getMessage());
		                }
		                FacebookRequestError error = respuesta.getError();
		                if (error != null) {
		                    Toast.makeText(postEditorView.getActivity().getApplicationContext(), error.getErrorMessage(), Toast.LENGTH_SHORT).show();
		                } else {
		                	Toast.makeText(postEditorView.getActivity().getApplicationContext(), "PostID: "+postId, Toast.LENGTH_LONG).show();
		                }
		                
		                postEditorView.hideProgressDialog();
		            }
		        };
		        Request consulta = new Request(sesion, "me/feed", postParametros, HttpMethod.POST, callback);
		        
		        RequestAsyncTask tarea = new RequestAsyncTask(consulta);
		        tarea.execute();
		    } else {
		    	Intent fb_activity = new Intent(postEditorView.getActivity(), LoginActivity.class);
		    	postEditorView.getActivity().startActivityForResult(fb_activity, REQUEST_FACEBOOK_LOGIN);
		    }
		}
	}
	
	private boolean esSubconjunto(Collection<String> subset, Collection<String> superset) {
	    for (String string : subset) {
	        if (!superset.contains(string)) {
	            return false;
	        }
	    }
	    return true;
	}
	
	/**
	 * Borra un Post local y remotamente.
	 */
	private void deletePost() {
//		TODO: A�adir confirmaci�n.
		if(post_id == MainActivityCtrl.NEW_POST) return;
		AsyncHttpPost client = new AsyncHttpPost(new DeletePostListener());
		client.putHeader("Authorization", "Bearer " + blog.getToken()); 
		client.putHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
		client.execute(new String[] {Blog.REST_URL + "/sites/" + String.valueOf(blog.getId()) + "/posts/" + String.valueOf(post_id) + "/delete"});
	}
	
	/**
	 * Lanza el Activity de la c�mara.
	 */
	private void dispatchTakePictureIntent() {
	    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
	    postEditorView.getActivity().startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
	}
	
	private int getBlogId() {
		return postEditorView.getActivity().getIntent().getExtras().getInt("blog_id");
	}
	
	private int getPostId() {
		return postEditorView.getActivity().getIntent().getExtras().getInt("post_id");
	}
	
	/**
	 * 
	 * @author Ignacio Javier Kovacs
	 *
	 */
	private class SyncPostListener implements AsyncTaskListener {

		@Override
		public void onPreExecute() {
			postEditorView.showProgressDialog();
		}

		@Override
		public void onPostExecute(String result) {
//			Post post = null;
			
			try {			
				/* Obtener post */
				JSONObject jPost= new JSONObject(result);
				
				/* Obtener post y actualizarlo, o insertarlo */
				post = JSONParser.getPost(jPost);
				post.setBlogId(blog.getId());
				
				if(database.getPost(post.getId()).getRawModified().before(post.getRawModified())) {
					/* Si fue modificado (ver fecha)... */
					database.update(post);
				}
			}
			catch (JSONException e) {
				Log.e("[JSONException]", e.getMessage());
			}
			
			/* Rellenar campos del editor. */
			postEditorView.setPostTitle(post.getTitle());
			postEditorView.setPostContent(post.getContent());
			postEditorView.setPostExcerpt(post.getExcerpt());
			postEditorView.setPostStatus(post.getStatus());
			
			/* Ocultar di�logo de espera. */
			postEditorView.hideProgressDialog(); 
		}
	}
	
	/**
	 * 
	 * @author Ignacio Javier Kovacs
	 *
	 */	
	private class SendPostListener implements AsyncTaskListener {

		@Override
		public void onPreExecute() {
			postEditorView.showProgressDialog();
		}

		@Override
		public void onPostExecute(String result) {
			try {
//				Post post = JSONParser.getPost(new JSONObject(result));
				post = JSONParser.getPost(new JSONObject(result));
				post.setBlogId(blog.getId());
				
				if(post_id != MainActivityCtrl.NEW_POST)
					database.update(post);
				else
					database.insert(post);
				
				shareOnFacebook(post);
			}
			catch(JSONException e) {
				Log.e("[JSONException]", e.getMessage());
			}
			
//			postEditorView.hideProgressDialog();
//			postEditorView.getActivity().setResult(Activity.RESULT_OK, null);
//			postEditorView.getActivity().finish();
		}
	}
	
	private class DeletePostListener implements AsyncTaskListener {

		@Override
		public void onPreExecute() {
			postEditorView.showProgressDialog();			
		}

		@Override
		public void onPostExecute(String result) {
			try {
//				Post post = JSONParser.getPost(new JSONObject(result));
				post = JSONParser.getPost(new JSONObject(result));
				
				if(post.getStatus().contentEquals("trash")){
					database.update(post);
					postEditorView.setPostStatus(post.getStatus());
				}
				else if(post.getStatus().contentEquals("deleted")){
					database.delete(post);
					postEditorView.getActivity().setResult(Activity.RESULT_OK);
					postEditorView.getActivity().finish();
				}
				
			}
			catch(JSONException e) {
				Log.e("[JSONException]", e.getMessage());
			}
			
			postEditorView.hideProgressDialog();
		}
	}
}
